/******************************************************************************
 *                  Shanghai ChipON Micro-Electronic Co.,Ltd
 ******************************************************************************
 *  @File Name        : kf8a100fxx_spi.c
 *  @Author           : ChipON AE/FAE Group
 *  @Date             : 2023-12-19
 *  @HW Version       : KF8A100Fxx
 *  @Lib Version      : V2.0.1
 *  @Description      : This file provides the driver for the spi module
 ******************************************************************************
 *  Copyright (C) by Shanghai ChipON Micro-Electronic Co.,Ltd
 *  All rights reserved.
 *
 *  This software is copyright protected and proprietary to
 *  Shanghai ChipON Micro-Electronic Co.,Ltd.
 *****************************************************************************/
/******************************************************************************
 *  |Date        |Version  |Author       |Description
 ******************************************************************************
 *  |2023-12-27  |V2.0     |Wang Junxiong|New creat
 *****************************************************************************/

/******************************************************************************
 **                     QAC Warnings
 *****************************************************************************/
/* PRQA S 0436 EOF #8-bit MCU Features: Direct Write Registers. */
/* PRQA S 1291, 1820, 1821, 1822, 1823, 1851, 1853, 3715, 3757, 3760 EOF #Registers are essentially unsigned numbers. */
/* PRQA S 2754 EOF #Level 7 problem due to unsupported assembly instructions. */
/* PRQA S 3768, 3771, 4130, 4393, 4434, 4443, 4446, 4461, 4532 EOF #Registers are essentially unsigned numbers. */

/******************************************************************************
 *                      Include Files
 *****************************************************************************/
#include "kf8a100fxx_spi.h"
/******************************************************************************
 *                      Macro Definitions
 *****************************************************************************/

/******************************************************************************
 *                      Constants
 *****************************************************************************/

/******************************************************************************
 *                      Type definitions
 *****************************************************************************/

/******************************************************************************
 *                      Variables
 *****************************************************************************/

/******************************************************************************
 *                      Function definitions
 *****************************************************************************/

/**
 * @brief SPI Initialization
 *
 * @param Mode spi mode and frequency division
 * @param Cpol Chip Select Active Polarity
 * @param Cpha Chip Select Active Polarity
 */
void Spi_Init(Spi_ModeType Mode, Spi_CpolModeType Cpol, Spi_CphaModeType Cpha)
{
    SSCIEN   = 0u;
    SSCICTL0 = (uint8_t)Mode;
    SSCICTL1 = 0x00u;
    SSCICKP  = (uint8_t)Cpol;
    CKEGE    = (uint8_t)Cpha;
    SSCIEN   = 1u;
}

/**
 * @brief SPI DeInitialization
 *
 */
void Spi_DeInit(void)
{
    SSCICTL0 = 0x00u;
    SSCICTL1 = 0x00u;
    SSCISTA  = 0x00u;
}

/**
 * @brief Enable or disable I2C/SPI/SSCIEN
 *
 * @param State 0: disable, 1: enable
 */
void Spi_Enable(uint8_t State)
{
    SSCIEN = State;
}

/**
 * @brief SPI master sends one byte of data
 *
 * @param Data Send data
 * @return uint8_t receive data
 */
uint8_t Spi_MasterSendOneByteData(uint8_t Data)
{
    uint16_t timeout = SPI_TIMEOUT_CONFIG;

    SSCIBUFR = Data;
    while ((SSCIIF == 0u) && (timeout > 0u))
    {
        timeout = timeout - 1u;
    }
    SSCIIF = 0u;
    /* PRQA S 3957 1 #Registers are essentially unsigned numbers. */
    return SSCIBUFR;
}

/**
 * @brief SPI sends data of length Len
 *
 * @attention This function cannot be called within an interrupt service routine.
 *
 * @param TxData Send Data Address
 * @param RxData receive data address
 * @param Len lengths
 * @return Spi_StatusType
 * 0: SPI_OK,
 * 1: SPI_TIMEOUT,
 */
Spi_StatusType Spi_MasterTxRxData(const uint8_t *TxData, uint8_t *RxData, uint8_t Len)
{
    uint16_t       timeout;
    Spi_StatusType state = SPI_OK;

    uint8_t i = 0u;
    SSCIIF    = 0u;
    for (; i < Len; i++)
    {
        SSCIBUFR = TxData[i];
        timeout  = SPI_TIMEOUT_CONFIG;
        while ((SSCIIF == 0u) && (timeout > 0u))
        {
            timeout = timeout - 1u;
        }
        if (timeout == 0u)
        {
            state = SPI_TIMEOUT;
            break;
        }
        else
        {
            /* nothing */
        }
        SSCIIF    = 0u;
        RxData[i] = SSCIBUFR;
    }
    return state;
}

/**
 * @brief SPI sends data of length Len
 *
 * @attention This function cannot be called within an interrupt service routine.
 *
 * @param TxData Send Data Address
 * @param Len lengths
 * @return Spi_StatusType
 * 0: SPI_OK,
 * 1: SPI_TIMEOUT,
 */
Spi_StatusType Spi_MasterTxData(const uint8_t *TxData, uint8_t Len)
{
    uint16_t       timeout;
    Spi_StatusType state = SPI_OK;

    uint8_t i = 0u;
    SSCIIF    = 0u;
    for (; i < Len; i++)
    {
        SSCIBUFR = TxData[i];
        timeout  = SPI_TIMEOUT_CONFIG;
        while ((SSCIIF == 0u) && (timeout > 0u))
        {
            timeout = timeout - 1u;
        }
        if (timeout == 0u)
        {
            state = SPI_TIMEOUT;
            break;
        }
        else
        {
            /* nothing */
        }
        SSCIIF = 0u;
        (void)SSCIBUFR;
    }
    return state;
}

/**
 * @brief SPI sends data of length Len
 *
 * @attention This function cannot be called within an interrupt service routine.
 *
 * @param TxData Send Data Address
 * @param RxData receive data address
 * @param Len lengths
 * @return Spi_StatusType
 * 0: SPI_OK,
 * 1: SPI_TIMEOUT,
 */
Spi_StatusType Spi_MasterRxData(uint8_t *RxData, uint8_t Len)
{
    uint16_t       timeout;
    Spi_StatusType state = SPI_OK;

    uint8_t i = 0u;
    SSCIIF    = 0u;
    for (; i < Len; i++)
    {
        SSCIBUFR = 0u;
        timeout  = SPI_TIMEOUT_CONFIG;
        while ((SSCIIF == 0u) && (timeout > 0u))
        {
            timeout = timeout - 1u;
        }
        if (timeout == 0u)
        {
            state = SPI_TIMEOUT;
            break;
        }
        else
        {
            /* nothing */
        }
        SSCIIF    = 0u;
        RxData[i] = SSCIBUFR;
    }
    return state;
}
/* EOF */
